package cn.turboinfo.dongying.api.gateway.admin.controller.cms;


import cn.turboinfo.dongying.api.domain.admin.service.cms.CmsArticleService;
import cn.turboinfo.dongying.api.domain.admin.service.cms.CmsCategoryService;
import cn.turboinfo.dongying.api.domain.common.service.file.FileAttachmentService;
import cn.turboinfo.dongying.api.domain.web.component.file.FileAttachmentHelper;
import cn.turboinfo.dongying.api.entity.admin.enumeration.cms.CmsArticleStatus;
import cn.turboinfo.dongying.api.entity.admin.enumeration.cms.CmsArticleType;
import cn.turboinfo.dongying.api.entity.admin.pojo.cms.*;
import cn.turboinfo.dongying.api.entity.common.pojo.file.FileAttachment;
import cn.turboinfo.dongying.api.gateway.admin.controller.BaseController;
import cn.turboinfo.dongying.api.gateway.admin.fo.cms.CmsArticleCreateFO;
import cn.turboinfo.dongying.api.gateway.admin.fo.cms.CmsArticleDisplayFO;
import cn.turboinfo.dongying.api.gateway.admin.fo.cms.CmsArticleSearchFO;
import cn.turboinfo.dongying.api.gateway.admin.fo.cms.CmsArticleUpdateFO;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.fo.LimitDataFO;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.fo.LimitFO;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.fo.RestResponseFO;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.fo.SortFO;
import cn.turboinfo.dongying.api.gateway.admin.controller.BaseController;
import cn.turboinfo.dongying.api.gateway.admin.fo.cms.CmsArticleCreateFO;
import cn.turboinfo.dongying.api.gateway.admin.fo.cms.CmsArticleDisplayFO;
import cn.turboinfo.dongying.api.gateway.admin.fo.cms.CmsArticleSearchFO;
import cn.turboinfo.dongying.api.gateway.admin.fo.cms.CmsArticleUpdateFO;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.fo.LimitDataFO;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.fo.LimitFO;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.fo.RestResponseFO;
import cn.turboinfo.dongying.api.gateway.admin.framework.http.fo.SortFO;
import cn.turboinfo.dongying.api.provider.admin.component.config.AdminKitConfig;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.sunshow.toolkit.core.base.enums.YesNoStatus;
import net.sunshow.toolkit.core.qbean.api.request.QPage;
import net.sunshow.toolkit.core.qbean.api.request.QRequest;
import net.sunshow.toolkit.core.qbean.api.request.QSort;
import net.sunshow.toolkit.core.qbean.api.response.QResponse;
import net.sunshow.toolkit.core.qbean.helper.component.request.QBeanCreatorHelper;
import net.sunshow.toolkit.core.qbean.helper.component.request.QBeanSearchHelper;
import net.sunshow.toolkit.core.qbean.helper.component.request.QBeanUpdaterHelper;
import net.sunshow.toolkit.core.qbean.helper.component.request.QPageRequestHelper;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/admin/cms/article")
@RequiredArgsConstructor
public class CmsArticleAdminController extends BaseController {
    private final CmsArticleService cmsArticleService;

    private final CmsCategoryService cmsCategoryService;

    private final FileAttachmentService fileAttachmentService;

    private final FileAttachmentHelper fileAttachmentHelper;

    private final AdminKitConfig adminKitConfig;

    @RequiresPermissions("cms:article:list")
    @RequestMapping("/list")
    public RestResponseFO list(@Valid CmsArticleSearchFO search, LimitFO page, SortFO sort) {
        QRequest request = QBeanSearchHelper.convertQRequest(search);

        if (sort.getSortFields() == null) {
            sort.setSortFields(new String[]{QCmsArticle.sort + "|" + QSort.Order.DESC.name(), QCmsArticle.publishedTime + "|" + QSort.Order.DESC.name()});
        }

        // 默认获取所有分类列表
        List<CmsCategory> categoryList = QPageRequestHelper.request(QRequest.newInstance(), QPage.newInstance().addOrder(QCmsArticle.id), cmsCategoryService::findAll);

        Map<Long, CmsCategory> categoryMap = categoryList.stream().collect(Collectors.toMap(CmsCategory::getId, Function.identity()));

        if (StringUtils.isNotEmpty(search.getCategoryCodes())) {
            List<Object> categoryIds = Lists.newArrayList();
            categoryList.forEach(category -> {
                if (search.getCategoryCodes().contains(category.getCode())) {
                    categoryIds.add(category.getId());
                }
            });
            if (categoryIds.size() > 0) {
                request.filterIn("categoryId", categoryIds);
            }
        }

        QResponse<CmsArticle> qresponse = cmsArticleService.findAll(request, page.toQPage(sort.toQSortList()));
        List<CmsArticleDisplayFO> foList = qresponse.getPagedData().stream().map(cmsArticle -> {
            CmsArticleDisplayFO fo = new CmsArticleDisplayFO();
            cmsArticle.setContent(null);
            fo.setArticle(cmsArticle);
            if (cmsArticle.getCategoryId() > 0) {
                fo.setCategory(categoryMap.get(cmsArticle.getCategoryId()));
            }
            return fo;
        }).collect(Collectors.toList());
        QResponse<CmsArticleDisplayFO> foqresponse = new QResponse<>(qresponse.getPage(), qresponse.getPageSize(), foList, qresponse.getTotal());
        return RestResponseFO.ok(LimitDataFO.fromQResponse(foqresponse));
    }

    @RequiresPermissions("cms:article:list")
    @GetMapping("/articleTypes")
    public RestResponseFO cmsArticleTypes() {
        return RestResponseFO.ok(CmsArticleType.getList());
    }


    @RequiresPermissions("cms:article:list")
    @GetMapping("/articleStatus")
    public RestResponseFO cmsArticleStatus() {
        return RestResponseFO.ok(CmsArticleStatus.getList());
    }


    @RequiresPermissions("cms:article:list")
    @GetMapping("/get/{id}")
    public RestResponseFO get(@PathVariable("id") Long id) {
        CmsArticle cmsArticle = cmsArticleService.getByIdEnsure(id);
        Optional<CmsCategory> category = cmsCategoryService.getById(cmsArticle.getCategoryId());
        if (category.isPresent()) {
            cmsArticle.setCategoryName(category.get().getName());
        }
        if (cmsArticle.getAttachId() != null) {
            Optional<FileAttachment> fileAttachment = fileAttachmentService.getById(cmsArticle.getAttachId());
            if (fileAttachment.isPresent()) {
                cmsArticle.setAttachName(fileAttachment.get().getDisplayName());
            }
        }
        return RestResponseFO.ok(cmsArticle);
    }

    @RequiresPermissions("cms:article:update")
    @PostMapping("/create")
    public RestResponseFO create(@RequestBody @Valid CmsArticleCreateFO fo) throws IOException {
        CmsArticleCreator.Builder builder = CmsArticleCreator.builder();
        QBeanCreatorHelper.copyPropertiesToCreatorBuilder(builder, CmsArticleCreator.class, fo);
        CmsArticle cmsArticle = cmsArticleService.save(builder.build());
        if (fo.getIsSync().equals(YesNoStatus.YES)) {
            CmsCategory loop = cmsCategoryService.getCategoryByCode("LOOP");

            if (loop != null && !Objects.equals(loop.getId(), cmsArticle.getId())) {
                cmsArticleService.save(builder
                        .withCategoryId(loop.getId())
                        .build());
            }
        }

        return RestResponseFO.ok(cmsArticle);
    }

    @RequiresPermissions("cms:article:update")
    @PostMapping("/update")
    public RestResponseFO update(@RequestBody @Valid CmsArticleUpdateFO fo) throws IOException {
        CmsArticleUpdater.Builder builder = CmsArticleUpdater.builder(fo.getId());
        QBeanUpdaterHelper.copyPropertiesToUpdateBuilder(builder, CmsArticleUpdater.class, fo);
        CmsArticle cmsArticle = cmsArticleService.update(builder.build());
        return RestResponseFO.ok(cmsArticle);
    }

    @RequiresPermissions("cms:article:delete")
    @PostMapping("/delete/{id}")
    @ResponseBody
    public RestResponseFO delete(@PathVariable("id") Long id) {
        CmsArticle cmsArticle = cmsArticleService.getByIdEnsure(id);
        cmsArticleService.deleteById(cmsArticle.getId());
        return RestResponseFO.ok(id);
    }
}
